Blender python バックグラウンド実行
非破壊で実行したいときに使える
参考
EZBaker/devices\blender\__init__.py
code:process.py
import argparse
import subprocess
import sys
import tempfile
from pathlib import Path
import bpy
from yfx_exporter.exporter import Exporter, ExportError #絶対パス指定する def run_export_process(context: bpy.types.Context) -> None:
scn = context.scene
settings = scn.yfx_exporter_settings
exporter = Exporter()
exporter.export(context, settings)
def start_foreground_export(context: bpy.types.Context) -> None:
run_export_process(context)
def start_background_export(context: bpy.types.Context) -> None:
export_settings = context.scene.yfx_exporter_settings.export_settings
abs_export_path = bpy.path.abspath(export_settings.export_path)
with tempfile.TemporaryDirectory() as temp_dir:
temp_file = str(Path(temp_dir) / "___yfx_exporter_temp___.blend")
bpy.ops.wm.save_as_mainfile(filepath=temp_file, copy=True, check_existing=False)
exec_script_path = __file__
exec_script_dir = Path(exec_script_path).parent
blender_args = [
bpy.app.binary_path,
"--factory-startup",
"--addons",
"--background",
temp_file,
"--python",
exec_script_path,
"--",
"--output",
abs_export_path,
]
with subprocess.Popen(
blender_args,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
encoding="UTF-8",
cwd=str(exec_script_dir),
) as proc:
print(proc.stdout.read())
msg_stderr = proc.stderr.read()
if msg_stderr:
raise ExportError(msg_stderr)
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--output", type=str)
output = args.output
context = bpy.context
settings = context.scene.yfx_exporter_settings
export_settings = settings.export_settings
export_settings.export_path = output
run_export_process(context)
引数指定で実行したファイルはサブスクリプトを読み込めないので、propertyのメンバ関数を使う↓
絶対パス指定すればいける
code:property.py
class YFX_EXPORTER_PG_settings(bpy.types.PropertyGroup):
export_settings: bpy.props.PointerProperty(type=YFX_EXPORTER_PG_export_settings)
is_subprocess: bpy.props.BoolProperty()
def export(self, context: bpy.types.Context) -> None:
run_export_process(context)
カレントディレクトリを指定すれば不要(相対インポートはできない)
code:cwd.py
from yfx_exporter.exporter import Exporter // scriptで相対インポートはできない
with subprocess.Popen(
blender_args,
stdout=subprocess.PIPE,
encoding="UTF-8",
cwd=str(exec_script_dir), # カレントの指定が必要
) as proc:
print(proc.stdout.read())
main や引数もとれるぽい